/*
  Programa GEFE - Gestión de eventos lúdicos.
  Copyright (C) 2010  Antonio Ramírez Marti

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "acolitopersonas.h"
#include "ui_acolitopersonas.h"

#include <QSqlDatabase>
#include <QSqlQuery>
#include <QVariant>
#include <QVariantList>
#include <QMessageBox>
#include <QPersistentModelIndex>
#include <QItemSelectionModel>
#include <QModelIndex>
#include <QModelIndexList>
#include <QAbstractItemModel>


AcolitoPersonas::AcolitoPersonas(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::AcolitoPersonas)
{
    ui->setupUi(this);
    setup();
}

AcolitoPersonas::~AcolitoPersonas()
{
    delete ui;
    if(modeloPersonas)
        delete modeloPersonas;
    if(filtroGrupo)
        delete filtroGrupo;
    if(mapper)
        delete mapper;
}

void AcolitoPersonas::changeEvent(QEvent *e)
{
    QWidget::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        ui->retranslateUi(this);
        break;
    default:
        break;
    }
}


void AcolitoPersonas::setup()
{
    modeloPersonas=0;
    mapper=0;
    filtroGrupo=0;
    modeloHabitacion=0;
    mapperHabitacion=0;
    setConectado(false);
    setGrupoActual(-1);
}

void AcolitoPersonas::setConectado(bool estado)
{
    switch(estado)
    {
    case false:
        if(QSqlDatabase::contains("evento"))
            QSqlDatabase::database("evento").close();

        if(modeloPersonas)
        {
            delete modeloPersonas;
            modeloPersonas=0;
        }

        if(mapper)
        {
            delete mapper;
            mapper=0;
        }

        if(filtroGrupo)
        {
            delete filtroGrupo;
            filtroGrupo=0;
        }

        if(modeloHabitacion)
        {
            delete modeloHabitacion;
            ui->cambiarHabitacionButton->disconnect(this);  // ¡Te cazé! El problema de multiples apariciones de un dialogo, depende de las multiples
                                                            // llamadas a la macro 'connect', que realiza multiples conexiones, de tal forma que cada
                                                            // vez que se emite la señal, se llama n veces al slot conectado, siendo n el numero de
                                                            // conexiones realizadas
            modeloHabitacion=0;
        }

        if(mapperHabitacion)
        {
            delete mapperHabitacion;
            mapperHabitacion=0;
        }

        this->setGrupoActual(-1);
        break;

    case true:

        //Creamos el modelo de personas y lo asociamos con la tabla asistente
        modeloPersonas=new ModeloAsistente(this,QSqlDatabase::database("evento",true));
        modeloPersonas->setEditStrategy(QSqlTableModel::OnFieldChange);

        //Creamos el mapper y lo conectamos con las lineas de edicion
        mapper=new QDataWidgetMapper(this);

        mapper->setModel(modeloPersonas);
        mapper->addMapping(ui->nombreEdit,modeloPersonas->fieldIndex("nombre"));
        mapper->addMapping(ui->apellidosEdit,modeloPersonas->fieldIndex("apellido"));
        mapper->addMapping(ui->dniEdit,modeloPersonas->fieldIndex("dni"));
        mapper->addMapping(ui->emailEdit,modeloPersonas->fieldIndex("email"));
        mapper->addMapping(ui->ingresoCheckBox,modeloPersonas->fieldIndex("haPagado"));

        mapper->setSubmitPolicy(QDataWidgetMapper::AutoSubmit);

        //Asociamos el modelo a la vista
        ui->vistaPersonas->setModel(modeloPersonas);

        ui->vistaPersonas->setColumnHidden(modeloPersonas->fieldIndex("IDasis"),true);
        ui->vistaPersonas->setColumnHidden(modeloPersonas->fieldIndex("haPagado"),true);
        ui->vistaPersonas->setColumnHidden(modeloPersonas->fieldIndex("IDgrupo"),true);
        ui->vistaPersonas->resizeColumnToContents(modeloPersonas->fieldIndex("email"));

        //Creamos el filtro de grupo y lo conectamos al mapper y a la vista de grupos
        filtroGrupo=new QSortFilterProxyModel(this);

        filtroGrupo->setSourceModel(modeloPersonas);
        filtroGrupo->setFilterKeyColumn(modeloPersonas->fieldIndex("IDgrupo"));

        mapper->addMapping(this,modeloPersonas->fieldIndex("IDgrupo"),"grupo");

        ui->vistaGrupo->setModel(filtroGrupo);

        ui->vistaGrupo->setColumnHidden(modeloPersonas->fieldIndex("IDasis"),true);
        ui->vistaGrupo->setColumnHidden(modeloPersonas->fieldIndex("haPagado"),true);
        ui->vistaGrupo->setColumnHidden(modeloPersonas->fieldIndex("IDgrupo"),true);

        //Creamos el modelo de habitaciones
        modeloHabitacion=new QSqlTableModel(this,QSqlDatabase::database("evento"));

        modeloHabitacion->setTable("asignado_a");
        modeloHabitacion->select();

        //Creamos el mapper de habitaciones y lo asociamos a la interfaz

        mapperHabitacion=new QDataWidgetMapper(this);

        mapperHabitacion->setModel(modeloHabitacion);

        mapperHabitacion->addMapping(ui->habitacionLine,modeloHabitacion->fieldIndex("codHab"));
        mapperHabitacion->toFirst();

        //Asociamos la vista al slot de filtrado de habitaciones
        connect(ui->vistaPersonas->selectionModel(),SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),this,SLOT(filtraHabitacion(QModelIndex,QModelIndex)));

        //Acciones de las vistas
        ui->vistaPersonas->setContextMenuPolicy(Qt::ActionsContextMenu);
        ui->vistaGrupo->setContextMenuPolicy(Qt::ActionsContextMenu);

        ui->vistaPersonas->addAction(ui->actionEliminar_asistentes);
        ui->vistaGrupo->addAction(ui->actionTransferir_a_Nuevo_Grupo);

        connect(ui->actionEliminar_asistentes,SIGNAL(triggered()),this,SLOT(eliminarAsistentes()));
        connect(ui->actionTransferir_a_Nuevo_Grupo,SIGNAL(triggered()),this,SLOT(transferirANuevoGrupo()));

        //Conectamos el boton de cambio de habitacion con su slot
        connect(ui->cambiarHabitacionButton,SIGNAL(clicked()),this,SLOT(dialogoCambiaHabitacion()));

        //Inicializamos
        mapper->toFirst();
        connect(ui->vistaPersonas->selectionModel(),SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),mapper,SLOT(setCurrentModelIndex(QModelIndex)));
        modeloPersonas->select();

        break;

    default:
        break;
    }

    flagConectado=estado;
}

void AcolitoPersonas::setGrupoActual(int g)
{
    if(filtroGrupo)
        filtroGrupo->setFilterFixedString(QVariant(g).toString());

    grupoAsistente=g;

}

void AcolitoPersonas::addAsistentesDialog()
{
    NuevoAsistenteDialog *dialog=new NuevoAsistenteDialog(this);

    connect(dialog,SIGNAL(nuevosAsistentes(QStandardItemModel*)),this,SLOT(nuevosAsistentes(QStandardItemModel*)));

    dialog->show();
}

void AcolitoPersonas::nuevosAsistentes(QStandardItemModel *grupo)
{
    QStandardItemModel *asistentes=grupo;

    QVariantList nombres,apellidos,dni,correos,pagos,grupos;
    int IDgrupo;
    {
        QSqlDatabase::database("evento").transaction();

        QSqlQuery query(QSqlDatabase::database("evento"));

        query.prepare("INSERT INTO grupo(nombre,tamGrupo) VALUES(NULL,?)");
        query.addBindValue(asistentes->rowCount());

        query.exec();
        query.clear();
        query.exec("SELECT last_insert_rowid()");

        query.next();
        IDgrupo=query.value(0).toInt();

        query.clear();

        query.prepare("INSERT INTO asistente(nombre,apellido,dni,email,haPagado,IDgrupo)"
                      "VALUES(?,?,?,?,?,?)");

        for(int i=0;i<asistentes->rowCount();i++)
        {
            nombres << asistentes->item(i,0)->data(Qt::EditRole);
            apellidos << asistentes->item(i,1)->data(Qt::EditRole);
            dni << asistentes->item(i,2)->data(Qt::EditRole);
            correos << asistentes->item(i,3)->data(Qt::EditRole);
            pagos << asistentes->item(i,4)->data(Qt::EditRole);
            grupos <<IDgrupo;
        }

        query.addBindValue(nombres);
        query.addBindValue(apellidos);
        query.addBindValue(dni);
        query.addBindValue(correos);
        query.addBindValue(pagos);
        query.addBindValue(grupos);

        query.execBatch();

        QSqlDatabase::database("evento").commit();
    }
    delete asistentes;
    modeloPersonas->select();
    mapper->toFirst();
}

void AcolitoPersonas::eliminarAsistentes()
{
    QModelIndexList asistentesParaEliminar;

    asistentesParaEliminar=ui->vistaPersonas->selectionModel()->selectedRows();

    modeloPersonas->removeRows(asistentesParaEliminar.at(0).row(),asistentesParaEliminar.size());
}

void AcolitoPersonas::transferirANuevoGrupo()
{
    QModelIndexList asistentesParaCambiar;

    asistentesParaCambiar=ui->vistaGrupo->selectionModel()->selectedRows();

    int nuevoGrupo;
    {
        QSqlDatabase::database("evento").transaction();

        QSqlQuery query("INSERT INTO grupo(nombre) VALUES(NULL)",QSqlDatabase::database("evento"));

        query.clear();
        query.exec("SELECT last_insert_rowid()");

        query.next();
        nuevoGrupo=query.value(0).toInt();

        query.clear();

        foreach(QModelIndex asistente,asistentesParaCambiar)
            filtroGrupo->setData(filtroGrupo->index(asistente.row(),modeloPersonas->fieldIndex("IDgrupo")),QVariant(nuevoGrupo));


        QSqlDatabase::database("evento").commit();
    }
}

///< @bug Si el grupo no tiene entrada dentro de de la tabla asignado_a, el QLineEdit tiene la última codHab selecionada
void AcolitoPersonas::filtraHabitacion(const QModelIndex &actual, const QModelIndex &anterior)
{
    QString grupo;
    if(isConectado())
    {
        QString filtro="IDgrupo=";
        grupo=modeloPersonas->data(modeloPersonas->index(actual.row(),modeloPersonas->fieldIndex("IDgrupo")),Qt::EditRole).toString();
        modeloHabitacion->setFilter(filtro+grupo);
        mapperHabitacion->toFirst();
    }
}

void AcolitoPersonas::reloadModelos()
{
    if(isConectado())
    {
        modeloPersonas->select();
        modeloHabitacion->select();
    }
}

void AcolitoPersonas::trasladaGrupo()
{

}

void AcolitoPersonas::dialogoCambiaHabitacion()
{
    cambioHabitacionDialog *dialog;
    int resultado;
    QVariant grupo;

    grupo=QVariant(this->grupoActual());

    dialog=new cambioHabitacionDialog(this,grupo);

    resultado=dialog->exec();
    delete dialog;

    if(resultado)          //Accepted, se ha cambiado el grupo
    {
        this->setConectado(false);
        this->setConectado(true);
        emit this->cambioHabitacion();
    }

}
